use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, DeriveInput, ItemFn, AttributeArgs, NestedMeta, Lit, Meta};

// ============================================================================
// 函数式宏 (Function-like Macro)
// ============================================================================

/// 函数式宏：创建用户结构体
/// 使用方式：create_user!(name, age)
#[proc_macro]
pub fn create_user(input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as syn::ExprTuple);
    
    if input.elems.len() != 2 {
        return TokenStream::from(quote! {
            compile_error!("create_user! 需要两个参数：name 和 age");
        });
    }
    
    let name = &input.elems[0];
    let age = &input.elems[1];
    
    let expanded = quote! {
        User {
            name: #name.to_string(),
            age: #age,
            id: generate_id(),
        }
    };
    
    TokenStream::from(expanded)
}

/// 函数式宏：创建向量
/// 使用方式：my_vec![1, 2, 3]
#[proc_macro]
pub fn my_vec(input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as syn::ExprArray);
    
    let elements = input.elems;
    
    let expanded = quote! {
        {
            let mut v = Vec::new();
            #(v.push(#elements);)*
            v
        }
    };
    
    TokenStream::from(expanded)
}

// ============================================================================
// 属性宏 (Attribute Macro)
// ============================================================================

/// 属性宏：为函数添加日志
/// 使用方式：#[log_function]
#[proc_macro_attribute]
pub fn log_function(attr: TokenStream, item: TokenStream) -> TokenStream {
    let _attr = parse_macro_input!(attr as AttributeArgs);
    let input = parse_macro_input!(item as ItemFn);
    
    let fn_name = &input.sig.ident;
    let fn_block = &input.block;
    let fn_inputs = &input.sig.inputs;
    let fn_output = &input.sig.output;
    let fn_vis = &input.vis;
    let fn_attrs = &input.attrs;
    
    let expanded = quote! {
        #(#fn_attrs)*
        #fn_vis fn #fn_name #fn_inputs #fn_output {
            println!("[LOG] 进入函数: {}", stringify!(#fn_name));
            let result = #fn_block;
            println!("[LOG] 离开函数: {}", stringify!(#fn_name));
            result
        }
    };
    
    TokenStream::from(expanded)
}

/// 属性宏：为函数添加性能监控
/// 使用方式：#[benchmark]
#[proc_macro_attribute]
pub fn benchmark(attr: TokenStream, item: TokenStream) -> TokenStream {
    let _attr = parse_macro_input!(attr as AttributeArgs);
    let input = parse_macro_input!(item as ItemFn);
    
    let fn_name = &input.sig.ident;
    let fn_block = &input.block;
    let fn_inputs = &input.sig.inputs;
    let fn_output = &input.sig.output;
    let fn_vis = &input.vis;
    let fn_attrs = &input.attrs;
    
    let expanded = quote! {
        #(#fn_attrs)*
        #fn_vis fn #fn_name #fn_inputs #fn_output {
            use std::time::Instant;
            let start = Instant::now();
            let result = #fn_block;
            let duration = start.elapsed();
            println!("[BENCHMARK] {} 执行时间: {:?}", stringify!(#fn_name), duration);
            result
        }
    };
    
    TokenStream::from(expanded)
}

/// 属性宏：为结构体添加调试信息
/// 使用方式：#[debug_struct]
#[proc_macro_attribute]
pub fn debug_struct(attr: TokenStream, item: TokenStream) -> TokenStream {
    let _attr = parse_macro_input!(attr as AttributeArgs);
    let input = parse_macro_input!(item as DeriveInput);
    
    let struct_name = &input.ident;
    let struct_fields = match &input.data {
        syn::Data::Struct(data) => &data.fields,
        _ => return TokenStream::from(quote! {
            compile_error!("debug_struct 只能用于结构体");
        }),
    };
    
    let field_names: Vec<_> = struct_fields.iter()
        .map(|field| &field.ident)
        .collect();
    
    let expanded = quote! {
        #input
        
        impl #struct_name {
            fn debug_info(&self) {
                println!("[DEBUG] 结构体: {}", stringify!(#struct_name));
                #(println!("  {}: {:?}", stringify!(#field_names), self.#field_names);)*
            }
        }
    };
    
    TokenStream::from(expanded)
}

// ============================================================================
// 派生宏 (Derive Macro)
// ============================================================================

/// 派生宏：为结构体实现 Clone trait
/// 使用方式：#[derive(MyClone)]
#[proc_macro_derive(MyClone)]
pub fn my_clone_derive(input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as DeriveInput);
    let name = &input.ident;
    
    let expanded = quote! {
        impl Clone for #name {
            fn clone(&self) -> Self {
                Self {
                    // 这里需要根据字段类型生成克隆代码
                    // 简化版本，实际需要更复杂的处理
                }
            }
        }
    };
    
    TokenStream::from(expanded)
} 